using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using CommandLineParser.Arguments;
using uTILLIty.Rave.Contract.Job;
using uTILLIty.Rave.Core.Manager;

namespace uTILLIty.Rave.Commandline
{
	/// <summary>
	/// A base class for job-processing commands
	/// </summary>
	public abstract class BaseCreateCommand : BaseCommand
	{
		/// <summary>
		/// A list of comma-separated key/value pairs to add to the NVelocity-context
		/// </summary>
		/// <remarks>
		/// Use a backslash \ to escape the separatation signs = and , in the value part
		/// </remarks>
		[ValueArgument(typeof(string), 'n', "env", Optional = true, Description = "A list of comma-separated key/value pairs to add to the NVelocity-context",
			FullDescription = @"Use a backslash \ to escape the separatation signs = and , in the value part",
			Example = "-n \"server=srv01,domain=%USERDOMAIN%,fullName=Doe\\, John\"")]
		public string MergeVariables;

		private static readonly Regex CommandlineMergeVariableParseRegex = new Regex(@"(?ixn)(?<key>[^=]+)=(?<value>.+?)(?<!\\)(,|$)");
		
		/// <summary>
		/// The <see cref="CsvManager"/> to use
		/// </summary>
		/// <remarks>
		/// is injected via the ctor
		/// </remarks>
		protected readonly CsvManager CsvManager;

		/// <summary>
		/// The default CTR which initializes the instance with all required objects
		/// </summary>
		/// <param name="csvManager"></param>
		protected BaseCreateCommand(CsvManager csvManager)
		{
			CsvManager = csvManager;
		}

		/// <summary>
		/// Parses the merge-variables passed from the commandline
		/// </summary>
		internal protected virtual void ParseCommandlineMergeVariable(List<MergeVariable> list, string expression, Encoding encoding)
		{
			var matches = CommandlineMergeVariableParseRegex.Matches(Environment.ExpandEnvironmentVariables(expression));
			foreach (Match match in matches)
			{
				if (!match.Success)
					continue;
				var key = match.Groups["key"].Value;
				var value = match.Groups["value"].Value.Replace("\\,", ",");
				var var = MergeVariable.Create(key, value);
				if (list.Contains(var))
					list.Single(v => v == var).Value = var.Value;
				else
					list.Add(var);
			}
		}
	}
}